package name.cyrax.red.jpv.impl.vectors;

import name.cyrax.red.jpv.api.vectors.Vector;
import name.cyrax.red.jpv.impl.adapters.NumericAdapters;

public final class Vectors
{
	private Vectors() {};
	
	public static Vector<Integer> newFill(final int size, final int v)
	{
		return new IntegerVectorImpl() {
			
			@Override public int getInteger(int index)
			{
				checkIndex(index);
				return v;
			}
			
			@Override public int size()
			{
				return size;
			}
		};
	}
	
	public static Vector<Integer> newInstance(final int v)
	{
		return new IntegerVectorImpl() {
			
			@Override public int getInteger(int index)
			{
				checkIndex(index);
				return v;
			}
			
			@Override public int size()
			{
				return 1;
			}
		};
	}

	public static Vector<Integer> newInstance(final int... v)
	{
		return newInstance0(v.clone());
	}
	
	static Vector<Integer> newInstance0(final int[] v)
	{
		return new IntegerVectorImpl() {
			
			@Override public int getInteger(int index)
			{
				checkIndex(index);
				return v[index];
			}
			
			@Override public int size()
			{
				return v.length;
			}
		};
	}
	
	static Vector<Integer> newInstance0(final int size, final int[] v)
	{
		NumericAdapters.checkArraySize(v, size);
		return new IntegerVectorImpl() {
			
			@Override public int getInteger(int index)
			{
				checkIndex(index);
				return v[index];
			}
			
			@Override public int size()
			{
				return size;
			}
		};
	}

	public static Vector<Double> newFill(final int size, final double v)
	{
		return new DoubleVectorImpl() {
			
			@Override public double getDouble(int index)
			{
				checkIndex(index);
				return v;
			}
			
			@Override public int size()
			{
				return size;
			}
		};
	}
	
	public static Vector<Double> newInstance(final double v)
	{
		return new DoubleVectorImpl() {
			
			@Override public double getDouble(int index)
			{
				checkIndex(index);
				return v;
			}
			
			@Override public int size()
			{
				return 1;
			}
		};
	}

	public static Vector<Double> newInstance(final double... v)
	{
		return newInstance0(v.clone());
	}
	
	static Vector<Double> newInstance0(final double[] v)
	{
		return new DoubleVectorImpl() {
			
			@Override public double getDouble(int index)
			{
				checkIndex(index);
				return v[index];
			}
			
			@Override public int size()
			{
				return v.length;
			}
		};
	}
	
	static Vector<Double> newInstance0(final int size, final double[] v)
	{
		NumericAdapters.checkArraySize(v, size);
		return new DoubleVectorImpl() {
			
			@Override public double getDouble(int index)
			{
				checkIndex(index);
				return v[index];
			}
			
			@Override public int size()
			{
				return size;
			}
		};
	}
		
	static Vector<Long> newInstance0(final long[] v)
	{
		return new LongVectorImpl() {
			
			@Override public long getLong(int index)
			{
				checkIndex(index);
				return v[index];
			}
			
			@Override public int size()
			{
				return v.length;
			}
		};
	}
}
